﻿using System;
using System.Text;
using System.Collections.Generic;

using Microsoft.SharePoint;

using RealDolmen.Helpers;

namespace RealDolmen.SharePoint.Helpers
{
    public class SPLookupHelper
    {
        #region GetLookupList
        public static SPList GetLookupList(string name, SPFieldCollection fields)
        {
            try
            {
                SPField field = fields.GetField(name);

                return GetLookupList(field, fields);
            }
            catch { return null; }
        }

        public static SPList GetLookupListByDisplayName(string displayName, SPFieldCollection fields)
        {
            try
            {
                SPField field = fields[displayName];

                return GetLookupList(field, fields);
            }
            catch { return null; }
        }

        public static SPList GetLookupListByInternalName(string internalName, SPFieldCollection fields)
        {
            try
            {
                SPField field = fields.GetFieldByInternalName(internalName);

                return GetLookupList(field, fields);
            }
            catch { return null; }
        }


        public static SPList GetLookupList(SPFieldLookup lookupField, SPWeb web)
        {
            SPList lookupList = null;

            if (lookupField != null)
            {
                Guid listGuid = Guid.Empty;
                if (lookupField.LookupList.Length > 30)
                {
                    try
                    {
                        listGuid = new Guid(lookupField.LookupList);
                    }
                    catch { }
                }

                if (lookupField.LookupList == "Docs")
                    return null;

                if (lookupField.LookupWebId != Guid.Empty && web.ID != lookupField.LookupWebId)
                {
                    // SPWeb.Site should not be disposed
                    SPSite site = web.Site;
                    SPWeb tempWeb = site.AllWebs[lookupField.LookupWebId];
                    if (listGuid != Guid.Empty)
                        lookupList = tempWeb.Lists[listGuid];
                    else
                        lookupList = tempWeb.Lists[lookupField.LookupList];
                    SPHelper.TryDisposeWeb(tempWeb);
                }
                else
                {
                    if (listGuid != Guid.Empty)
                        lookupList = web.Lists[listGuid];
                    else
                        lookupList = web.Lists[lookupField.LookupList];
                }
            }
            return lookupList;
        }

        public static SPList GetLookupList(SPField field, SPFieldCollection fields)
        {
            if (field is SPFieldLookup)
            {
                // SPFieldCollection.Web should not be disposed
                SPList list = GetLookupList(field as SPFieldLookup, fields.Web);

                return list;
            }
            return null;
        }

        public static string GetLookupFieldValueFromLookupItems(SPFieldLookup fieldLookup, SPListItemCollection lookupItems)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < lookupItems.Count; i++)
            {
                SPListItem listItem = lookupItems[i];
                sb.AppendFormat("{0};#{1}", listItem.ID, listItem[fieldLookup.LookupField]);
                if (i < lookupItems.Count - 1)
                {
                    sb.Append(";#");
                }
            }
            return sb.ToString();
        }

        public static string GetLookupFieldValueFromDisplayValue(SPField field, string data, SPWeb web)
        {
            SPFieldLookup fieldLookup = field as SPFieldLookup;
            SPList list = GetLookupList(fieldLookup, web);

            if (list != null)
            {
                SPQueryBuilder queryBuilder = new SPQueryBuilder();
                queryBuilder.AndEquals(fieldLookup.LookupField, data);

                SPListItemCollection results = list.GetItems(queryBuilder.ToQuery());

                return GetLookupFieldValueFromLookupItems(fieldLookup, results);
            }
            return data;
        }
        public static string GetLookupFieldValueFromDisplayValues(SPField field, List<string> data, SPWeb web)
        {
            SPFieldLookup fieldLookup = field as SPFieldLookup;
            SPList list = GetLookupList(fieldLookup, web);

            SPQueryBuilder queryBuilder = new SPQueryBuilder();

            foreach (string singleData in data)
            {
                queryBuilder.OrEquals(fieldLookup.LookupField, singleData);
            }

            SPListItemCollection results = list.GetItems(queryBuilder.ToQuery());

            return GetLookupFieldValueFromLookupItems(fieldLookup, results);
        }
        #endregion // GetLookupList

        #region GetLookupItem
        public static SPListItem GetLookupItem(SPItem item, SPField field)
        {
            SPList lookupList = GetLookupList(field, item.Fields);

            if (lookupList != null)
            {
                SPFieldLookupValue lookupValue = new SPFieldLookupValue(item[field.InternalName].ToString());
                return lookupList.Items[lookupValue.LookupId - 1];
            }
            return null;
        }
        #endregion // GetLookupItem

        #region ProcessLookupField
        public static void ProcessLookupField(SPField field, SPWeb web)
        {
            ProcessLookupField(field, web, false);
        }
        public static void ProcessLookupField(SPField field, SPWeb web, bool pushChangesToLists)
        {
            SPFieldLookup lookupField = field as SPFieldLookup;

            if (lookupField != null)
            {
                SPList list;
                try
                {
                    string url = lookupField.LookupList;
                    SPParser.ParseUrlPrefixInUrl(web, ref url, SPUrlType.ServerRelativeUrl);


                    list = web.GetList(url);
                    WrapperObject wo = new WrapperObject(field);
                    wo.Invoke("SetFieldAttributeValue", "List", list.ID.ToString("B"));
                    field.Update(pushChangesToLists);
                }
                catch { }
            }
        }
        #endregion // ProcessLookupField
    }
}
